<script lang="ts" setup>
// FluentUI components are registered in main.ts

import type { CheckboxShape, CheckboxSize } from '@fluentui/web-components';

const props = withDefaults(
  defineProps<{
    autofocus?: boolean;
    checked?: boolean;
    disabled?: boolean;
    indeterminate?: boolean;
    modelValue?: boolean;
    name?: string;
    required?: boolean;
    shape?: CheckboxShape;
    size?: CheckboxSize;
    value?: string;
  }>(),
  {
    modelValue: undefined,
    checked: false,
    indeterminate: false,
    disabled: false,
    shape: undefined,
    size: undefined,
    required: false,
    name: undefined,
    value: 'on',
    autofocus: false,
  },
);

const emit = defineEmits<{
  change: [event: Event, value: boolean];
  input: [event: Event, value: boolean];
  'update:modelValue': [value: boolean];
}>();

// Define slots
defineSlots<{
  default?: () => any;
  end?: () => any; // Content which can be provided after the input
  start?: () => any; // Content which can be provided before the input
}>();

const checkboxRef = ref<HTMLElement | null>(null);
const internalChecked = ref(props.checked);

// Handle modelValue prop for v-model support
const isControlled = computed(() => props.modelValue !== undefined);

// Update internal checked state when props change
watch(
  () => props.modelValue,
  (newVal) => {
    if (newVal !== undefined) {
      internalChecked.value = newVal;
    }
  },
);

watch(
  () => props.checked,
  (newVal) => {
    if (!isControlled.value) {
      internalChecked.value = newVal;
    }
  },
);

// Handle events
const handleChange = (event: Event) => {
  const target = event.target as HTMLInputElement;
  const newValue = target.checked;

  if (!isControlled.value) {
    internalChecked.value = newValue;
  }

  emit('update:modelValue', newValue);
  emit('change', event, newValue);
};

const handleInput = (event: Event) => {
  const target = event.target as HTMLInputElement;
  const newValue = target.checked;

  emit('input', event, newValue);
};

// Update the checkbox element when indeterminate changes
watch(
  () => props.indeterminate,
  (newVal) => {
    if (checkboxRef.value) {
      (checkboxRef.value as any).indeterminate = newVal;
    }
  },
);

// Set initial indeterminate state when mounted
onMounted(() => {
  if (checkboxRef.value && props.indeterminate) {
    (checkboxRef.value as any).indeterminate = props.indeterminate;
  }
});
</script>

<template>
  <fluent-checkbox
    ref="checkboxRef"
    :checked="isControlled ? modelValue : internalChecked"
    :disabled="disabled"
    :shape="shape"
    :size="size"
    :required="required"
    :name="name"
    :value="value"
    :autofocus="autofocus"
    @change="handleChange"
    @input="handleInput"
  >
    <!-- eslint-disable-next-line vue/no-deprecated-slot-attribute -->
    <span slot="start">
      <slot name="start"></slot>
    </span>
    <slot></slot>
    <!-- eslint-disable-next-line vue/no-deprecated-slot-attribute -->
    <span slot="end">
      <slot name="end"></slot>
    </span>
  </fluent-checkbox>
</template>

<style scoped></style>
